package com.example.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.core.enums.ResultCode;
import com.example.security.exception.ServiceException;
import com.example.system.component.elasticsearch.QuestionES;
import com.example.system.component.elasticsearch.QuestionRepository;
import com.example.system.component.manager.QuestionCacheManager;
import com.example.system.entity.DO.QuestionDO;
import com.example.system.entity.DTO.QuestionAddDTO;
import com.example.system.entity.DTO.QuestionEditDTO;
import com.example.system.entity.DTO.QuestionQueryDTO;
import com.example.system.entity.VO.QuestionDetailVO;
import com.example.system.entity.VO.QuestionVO;
import com.example.system.mapper.QuestionMapper;
import com.example.system.service.IQuestionService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class QuestionServiceImpl implements IQuestionService {
    @Autowired
    private QuestionMapper questionMapper;
    @Autowired
    private QuestionRepository questionRepository;
    @Autowired
    private QuestionCacheManager questionCacheManager;

    @Override
    public List<QuestionVO> list(QuestionQueryDTO questionQueryDTO) {
        // PageHelper 自动分页
        PageHelper.startPage(questionQueryDTO.getPageNum(), questionQueryDTO.getPageSize());
        return questionMapper.selectQuestionList(questionQueryDTO);
    }

    @Override
    public int edit(QuestionEditDTO questionEditDTO) {
        this.checkQuestionId(questionEditDTO.getQuestionId());
        QuestionDO editQuestionDO = new QuestionDO();
        BeanUtils.copyProperties(questionEditDTO, editQuestionDO);

        // 将编辑后的题目也存储到redis，es
        QuestionES questionES = new QuestionES();
        BeanUtil.copyProperties(editQuestionDO, questionES);
        questionRepository.save(questionES);
        return questionMapper.updateById(editQuestionDO);
    }

    @Override
    public QuestionDetailVO detail(Long questionId) {
        QuestionDO questionDO = this.checkQuestionId(questionId);
        QuestionDetailVO questionDetailVO = new QuestionDetailVO();
        BeanUtils.copyProperties(questionDO, questionDetailVO);
        return questionDetailVO;
    }

    @Override
    public int delete(Long questionId) {
        this.checkQuestionId(questionId);

        // 同时删除redis,es中的数据
        questionRepository.deleteById(questionId);
        questionCacheManager.deleteCache(questionId);
        return questionMapper.deleteById(questionId);
    }

    @Override
    public List<QuestionDO> getListByIds(List<Long> ids) {
        return questionMapper.selectBatchIds(ids);
    }

    @Override
    public boolean add(QuestionAddDTO questionAddDTO) {
        LambdaQueryWrapper<QuestionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QuestionDO::getTitle, questionAddDTO.getTitle());
        List<QuestionDO> questionList = questionMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(questionList)) {
            throw new ServiceException(ResultCode.FAILED_ALREADY_EXISTS);
        }
        QuestionDO question = new QuestionDO();
        BeanUtil.copyProperties(questionAddDTO, question);
        int insert = questionMapper.insert(question);
        if (insert <= 0) {
            return false;
        }
        // 存到数据库之后，还要存到 redis,es
        QuestionES questionES = new QuestionES();
        BeanUtil.copyProperties(question, questionES);
        questionRepository.save(questionES);
        questionCacheManager.addCache(question.getQuestionId());
        return true;
    }

    /**
     * 校验 questionId并查询
     * @param questionId questionId
     */
    private QuestionDO checkQuestionId(Long questionId) {
        LambdaQueryWrapper<QuestionDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(QuestionDO::getQuestionId, questionId);
        QuestionDO exists = questionMapper.selectOne(wrapper);
        if (exists == null) {
            throw new ServiceException(ResultCode.FAILED_NOT_EXISTS);
        }
        return exists;
    }
}
